/********************************************************************************
  * @file    compileprocess.h
  * @author  Lun Li
  * @version V2.2.0
  * @date    2022.7.8
  * @brief   This file contains all the functions prototypes for the CompileProcess.
  ******************************************************************************/

#ifndef COMPILEPROCESS_H
#define COMPILEPROCESS_H

#include <QProcess>
#include "programconfig.h"
#include "project.h"
#include "hierarchymodel.h"
#include "signalconnection.h"

/************
  * CompileProcess类，用于给用户提供命令行编译功能
  ***********/
class CompileProcess : public QProcess
{
    Q_OBJECT
public:
    explicit CompileProcess(const ProgramConfig *config,
                            QObject *parent = nullptr);
    ~CompileProcess();

    // 编译files文件列表中的所有文件，merge表示是否将文件分开编译
    void runCompile(const QList<Source *>&files,
                    Project *project,
                    bool merge = false);

    // 使用vvp来执行iverilog生成的中间文件
    void runVVP(Source *file,
                Project *project);

    // 执行任意命令
    void runAnyCommand(const QString &command);

    // 重载QProcess的startCommand函数，为命令隐式添加编译指令
    void startCommand(const QString &command,
                      OpenMode mode = ReadWrite);

    // 设置命令行的工作路径
    void setWorkingDirectory(const QString &dir);

    // 开启日志记录功能
    void openLog();

    // 关闭日志记录功能
    void closeLog();

    // 读入中间文件以获取代码模块层次
    static QList<HierarchyModel *> readVVPFile(const QString &fileName, Project *project);

signals:
    // 编译开始
    void compileStarted();

    // 编译程序有输入
    void compileInput(const QString &input);

    // 编译程序有输出
    void compileOutput(const QString &output);

    // 编译程序有提示
    void compileHint(const QString &hint);

    // 编译程序有错误
    void compileError(const QString &error);

    // 编译结束
    void compileFinished(const QList<HierarchyModel *> &hierModels);

    // vvp开始
    void VVPStarted();

    // vvp结束
    void VVPFinished();

private:
    // 添加iverilog编译指令
    void iverilogCmdTransform(QStringList &commands);

    // 添加vvp编译指令
    void vvpCmdTransform(QStringList &commands);

    // 是否开启日志记录
    bool m_isLogEnabled;

    // 是否在编译完成后读取设计层次
    bool m_isLoadHierarchyEnabled;

    // 程序配置文件
    const ProgramConfig *m_config;

    // 进程是否已开启
    bool m_isStarted = false;

    // 日志文件
    QFile inputLog, outputLog;
    QTextStream inputStream, outputStream;

    // 当前错误与输出
    QString currentError;
    QString currentOutput;

    // 中间文件格式
    struct VVPFormat
    {
        QString label;
        QString instanceName;
        QString definitionName;
        int instanceIndex;
        int definitionIndex;
        QString parentLabel;
        QStandardItemModel *variableListModel;
    };
};

#endif // COMPILEPROCESS_H
